package cfca.paperless.client.servlet._8_local.suning;

import java.io.File;
import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import cfca.paperless.client.bean.MultiDataBean;
import cfca.paperless.client.bean.ProofUserInfo;
import cfca.paperless.client.bean.SignLocation;
import cfca.paperless.client.servlet.PaperlessClient;
import cfca.paperless.client.servlet.PaperlessClientLocal;
import cfca.paperless.client.servlet.PaperlessLocalConfig;
import cfca.paperless.client.util.IoUtil;
import cfca.paperless.client.util.PaperlessUtil;
import cfca.paperless.client.util.PdfUtil;
import cfca.paperless.client.util.StringUtil;
import cfca.sadk.algorithm.common.Mechanism;
import cfca.sadk.x509.certificate.X509Cert;


/**
 * <pre>
 * Modify Information:
 * Author       Date          Description
 * ============ ============= ============================
 * zf           2018年4月8日         申请下载场景证书、签场景章
 * </pre>
 */
public class DownloadSceneAndSignatureLocalTest01 {
 
    public static void main(String[] args) throws Exception {
        try {
            long timeStart = System.currentTimeMillis();// 开始时间
            
            float coefficient = 0.75f;
            
            // 无纸化辅助接口的访问URL
            PaperlessClient clientExtBean = new PaperlessClient(PaperlessLocalConfig.extUrl, 10000, 60000);
            // 无纸化辅助接口的访问URL
            PaperlessClient clientAssistBean = new PaperlessClient(PaperlessLocalConfig.assistUrl, 10000, 60000);

            PaperlessClientLocal paperlessClientLocal = new PaperlessClientLocal(clientExtBean, clientAssistBean, PaperlessLocalConfig.operatorCode);
            paperlessClientLocal.initTimestampServer(PaperlessLocalConfig.timeServerUrl, "", "");
            
            
            // 待签章pdf
            String filePath = "./TestData/file.pdf";
            byte[] pdf = FileUtils.readFileToByteArray(new File(filePath));
            
            // 印模图片
            byte[] handwritingImage = FileUtils.readFileToByteArray(new File("./TestData/seal.png"));
       
            byte[] identificationFrontData = FileUtils.readFileToByteArray(new File("./TestData/1.png"));
            byte[] identificationBackData = FileUtils.readFileToByteArray(new File("./TestData/2.png"));
            List<MultiDataBean> list = new ArrayList<MultiDataBean>();
            list.add(new MultiDataBean(handwritingImage, "handwritingImage.png", "2"));// 手写签名图片
            list.add(new MultiDataBean(identificationFrontData, "identificationFrontImage.png", "2"));// 身份证正面
            list.add(new MultiDataBean(identificationBackData, "identificationBackImage.png", "2"));// 身份证反面

            String proofHashAndMultiData1[] = PaperlessUtil.getProofHashAndMultiData(list);
            String proofHashXml =  proofHashAndMultiData1[0];
            
            
            // 计算pdf内容hash
            String pdfContentHash = PdfUtil.calculatePdfContentHash(pdf, new Mechanism(Mechanism.SHA1));
            proofHashXml = addProofToXml(proofHashXml, "pdfHash.pdf", pdfContentHash);
            
            //申请场景证书要素
            ProofUserInfo proofUserInfo = generateProofUserInfo(proofHashXml);
          
            /* 申请下载场景证书 */
            String result = paperlessClientLocal.applyAndDownloadCert(proofUserInfo);
            X509Cert x509Cert = null;
            String code = StringUtil.getNodeText(result, "Code");
            // 返回值Code等于200代表后台处理成功
            if (code.equals("200")) {
                String certData = StringUtil.getXmlField(result, "Cert");
                x509Cert = new X509Cert(certData.getBytes());
            } else {
                String signMessage = StringUtil.getNodeText(result, "Message");
                throw new Exception(signMessage);
            }
 
            // 合成proofHash
            pdf = PdfUtil.compoundPdfDataByAttachment(pdf, proofHashXml.getBytes(), "proofHash.xml");
            // 合成多媒体文件
            for (MultiDataBean multiDataBean : list) {
                pdf = PdfUtil.compoundPdfDataByAttachment(pdf, multiDataBean.getMultiData(), multiDataBean.getFileName());
            }

            SignLocation signLocation = new SignLocation("代理人签名", "R", 0, 0);// 签名位置
            
            PrivateKey privateKey = paperlessClientLocal.getPrivateKey();
            
            //场景证书签章
            byte[] sealedPdfData = paperlessClientLocal.sealAutoPdfLocal(pdf, x509Cert, privateKey, handwritingImage, coefficient, signLocation);
            
           
            String outputFilePath = "./TestData/output/signAutoPdfProofHash-" + new File(filePath).getName() + ".pdf";
            System.out.println("pdfSealVerifier ok " + outputFilePath);
            IoUtil.write(outputFilePath, sealedPdfData);
        
            long timeEnd = System.currentTimeMillis();// 结束时间
            System.out.println("time:" + (timeEnd - timeStart));

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static ProofUserInfo generateProofUserInfo(String selfExtValue){
        
        /* 申请场景证书 要素  */
        String userName = "张珊珊";
        String identificationType = "0";
        String identificationNo = "454212556565656";
        String keyAlg = "RSA";
        int keyLength = 2048;
        return  new ProofUserInfo(userName, identificationType, identificationNo, keyAlg, keyLength, selfExtValue);
        
    }

    private static String addProofToXml(String xmlContent, String fileName, String hash) throws DocumentException {
        Document document = DocumentHelper.parseText(xmlContent);
        Element root = document.getRootElement();
        Element newElement = root.addElement("Proof");
        newElement.addAttribute("fileName", fileName);
        newElement.addAttribute("hash", hash);
        return document.asXML();
    }

}
